using System;
using System.Runtime.InteropServices;
using UnityEngine;

namespace DA.AnimGraph {

    [StructLayout(LayoutKind.Explicit)]
    [Serializable]
    public struct AUID : IEquatable<AUID> {
        [FieldOffset(0)] PropertyName name;
        [FieldOffset(0), SerializeField] ulong data;

        public bool isValid => data != 0;

        public AUID(PropertyName name) {
            data = 0;
            this.name = name;
        }
        public AUID(ulong value) {
            name = default;
            data = value;
        }
        public AUID(long value) {
            name = default;
            data = (ulong)value;
        }

        // 转入
        //public static implicit operator AUID(PropertyName name) {
        //    return new AUID(name);
        //}
        public static implicit operator AUID(string name) {
            return new AUID(name);
        }
        public static implicit operator AUID(int value) {
            return new AUID((ulong)value);
        }
        public static implicit operator AUID(uint value) {
            return new AUID((ulong)value);
        }
        public static implicit operator AUID(ulong value) {
            return new AUID(value);
        }
        // 转出
        public static explicit operator ulong(AUID value) {
            return value.data;
        }
        //
        public static bool operator ==(AUID lhs, AUID rhs) {
            return lhs.data == rhs.data;
        }
        public static bool operator !=(AUID lhs, AUID rhs) {
            return lhs.data != rhs.data;
        }
        public static bool operator ==(AUID lhs, string rhs) {
            return lhs == new AUID(rhs);
        }
        public static bool operator !=(AUID lhs, string rhs) {
            return lhs != new AUID(rhs);
        }
        public static bool operator >(AUID lhs, AUID rhs) {
            return lhs.data > rhs.data;
        }
        public static bool operator <(AUID lhs, AUID rhs) {
            return lhs.data < rhs.data;
        }

        public override int GetHashCode() {
            return name.GetHashCode();
        }

        public override bool Equals(object other) {
            return other is AUID && Equals((AUID)other);
        }
        public bool Equals(AUID other) {
            return this == other;
        }

        public override string ToString() {
            return ToPatternString();
        }
        public string ToDataString() {
            return data.ToString();
        }
        public string ToPatternString() {
            ulong b3 = data & 0b1111;
            ulong b2 = data >> 4 & 0xfffffffff;
            ulong b1 = data >> 40;
            return $"{b1}-{b2}-{b3}";
        }
        public string ToName() {
#if UNITY_EDITOR
            return name.ToString().Split(":")[0];
#else
            return name.ToString();
#endif
        }
    }
}
